using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Ent.Voice.Nomination;
using Ent.SqlDB;
namespace Ent.Voice
{
    public enum Authentication 
    { 
        InvalidIDPassword,
        Inactive,
        OK,
        None
    }
    public enum RegisterResponse { Error, UserCreated, UserIdNotAvailable, EmailIdInUse }
    public enum ActivationResponse { Error, InvalidActivation, Activated }
    public struct UserLogin
    {
        public Authentication Authenticated;
        public User Details;
    }
    public class User
    {
        public string UserID = "";
        public string Password = "";
        public string FName = "";
        public string LName = "";
        public string Email = "";
        public string Phone = "";
        public string PhotoId = "";
        public string AboutMe = "";
        public DateTime DOB = DateTime.MinValue;
        public string Location = "";
        public string Hobbies = "";
        public string Language = "";
        public int cntParticipate = 0;
        public int Points = 0;
        public int Views = 0;
        public int CntGold = 0;
        public int CntSilver = 0;
        public int CntBronze = 0;
        public bool IsAdmin = false;
        public bool Active = false;
        public DateTime Joined = DateTime.MinValue;
        #region DDL
        public static UserLogin DoLogin(string userId, string password)
        {
            UserLogin retValue = new UserLogin();
            retValue.Details = GetDetail(userId, password);
            if (retValue.Details == null)
                retValue.Authenticated = Authentication.InvalidIDPassword;
            else if (retValue.Details.Active == false)
                retValue.Authenticated = Authentication.Inactive;
            else
                retValue.Authenticated = Authentication.OK;
            return retValue;
        }
        public static Entry[] GetEntriesWithinRange(string userId, int startRange, int count, bool includeSuspended, string viewId, ref int total)
        {
            return GetEntriesWithinRange(userId, startRange, count, includeSuspended, viewId, ref total, OrderBy.Points);
        }
        public static Entry[] GetEntriesWithinRange(string userId, int startRange, int count, bool includeSuspended, string viewId, ref int total, OrderBy orderby)
        {
            if (count <= 0)
                throw new Exception("Count should be a positive integer.");
            if (startRange <= 0)
                throw new Exception("Start range should be a positive integer.");
            Entry[] retValue = Entry.Search(EntryFilter.User, userId, "", startRange, count, orderby.ToString(), includeSuspended, viewId, ref total);
            return retValue;
        }
        public static User GetUser(string userId)
        {
            Dictionary<string, object> pars = new Dictionary<string, object>();
            pars.Add("UserId", userId);
            pars.Add("incView", 1);
            ReaderResponse rr = Execute.SPReader("Voice_GetUserDetails", pars, null);
            if (rr.Table != null && rr.Table.Rows.Count > 0)
                return SetUser(rr.Table.Rows[0]);
            else
                return null;
        }
        private static User GetDetail(string userId, string password)
        {
            Dictionary<string, object> pars = new Dictionary<string, object>();
            pars.Add("UserId", userId);
            pars.Add("Password", password);
            ReaderResponse rr = Execute.SPReader("Voice_LoginUser", pars, null);
            Global.Log.Info((rr.Table == null ? "Table null" : rr.Table.Rows.Count.ToString() + " users found."));
            if (rr.Table != null && rr.Table.Rows.Count > 0)
                return SetUser(rr.Table.Rows[0]);
            else
                return null;
        }
        private static User SetUser(DataRow dr)
        {
            User retValue = new User();
            if (dr.Table.Columns.Contains("UserId")) retValue.UserID = dr["UserId"].ToString();
            if (dr.Table.Columns.Contains("FName")) retValue.FName = dr["FName"].ToString();
            if (dr.Table.Columns.Contains("LName")) retValue.LName = dr["LName"].ToString();
            if (dr.Table.Columns.Contains("Email")) retValue.Email = dr["Email"].ToString();
            if (dr.Table.Columns.Contains("Phone")) retValue.Phone = dr["Phone"].ToString();
            if (dr.Table.Columns.Contains("PhotoId")) retValue.PhotoId = dr["PhotoId"].ToString();
            if (dr.Table.Columns.Contains("Aboutme")) retValue.AboutMe = dr["Aboutme"].ToString();
            if (dr.Table.Columns.Contains("DOB")) retValue.DOB = dr["DOB"] != DBNull.Value ? Convert.ToDateTime(dr["DOB"]) : DateTime.MinValue;
            if (dr.Table.Columns.Contains("Location")) retValue.Location = dr["Location"].ToString();
            if (dr.Table.Columns.Contains("Hobbies")) retValue.Hobbies = dr["Hobbies"].ToString();
            if (dr.Table.Columns.Contains("Language")) retValue.Language = dr["Language"].ToString();
            if (dr.Table.Columns.Contains("cntParticipate")) retValue.cntParticipate = dr["cntParticipate"] != DBNull.Value ? Convert.ToInt32(dr["cntParticipate"]) : 0;
            if (dr.Table.Columns.Contains("Points")) retValue.Points = dr["Points"] != DBNull.Value ? Convert.ToInt32(dr["Points"]) : 0;
            if (dr.Table.Columns.Contains("Views")) retValue.Views = dr["Views"] != DBNull.Value ? Convert.ToInt32(dr["Views"]) : 0;
            if (dr.Table.Columns.Contains("CntGold")) retValue.CntGold = dr["CntGold"] != DBNull.Value ? Convert.ToInt32(dr["CntGold"]) : 0;
            if (dr.Table.Columns.Contains("CntSilver")) retValue.CntSilver = dr["CntSilver"] != DBNull.Value ? Convert.ToInt32(dr["CntSilver"]) : 0;
            if (dr.Table.Columns.Contains("CntBronze")) retValue.CntBronze = dr["CntBronze"] != DBNull.Value ? Convert.ToInt32(dr["CntBronze"]) : 0;
            if (dr.Table.Columns.Contains("Active")) retValue.Active = dr["Active"] != DBNull.Value ? Convert.ToBoolean(dr["Active"]) : false;
            if (dr.Table.Columns.Contains("IsAdmin")) retValue.IsAdmin = dr["IsAdmin"] != DBNull.Value ? Convert.ToBoolean(dr["IsAdmin"]) : false;
            if (dr.Table.Columns.Contains("Joined")) retValue.Joined = dr["Joined"] != DBNull.Value ? Convert.ToDateTime(dr["Joined"]) : DateTime.MinValue;
            return retValue;
        }
        public static User[] Search(string key, int startIndex, int rowcount, string orderby, ref int total)
        {
            Dictionary<string, object> pars = new Dictionary<string, object>();
            pars.Add("key", key);
            pars.Add("startIndex", startIndex);
            pars.Add("rowCount", rowcount);
            pars.Add("orderBy", orderby);
            Dictionary<string, VSqlDbType> outpars = new Dictionary<string, VSqlDbType>();
            outpars.Add("count", new VSqlDbType(SqlDbType.Int, -1));
            ReaderResponse rr = Execute.SPReader("Voice_SearchUser", pars, outpars);
            total = Convert.ToInt32(rr.OutParams["count"]);
            if (rr.Table != null && rr.Table.Rows.Count > 0)
            {
                User[] retValue = new User[rr.Table.Rows.Count];
                for (int i = 0; i < rr.Table.Rows.Count; i++)
                {
                    retValue.SetValue(SetUser(rr.Table.Rows[i]), i);
                }
                return retValue;
            }
            else
                return null;
        }
        public static User[] ListAllUsers(int startIndex, int rowcount, string orderby, ref int total)
        {
            Dictionary<string, object> pars = new Dictionary<string, object>();
            pars.Add("startIndex", startIndex);
            pars.Add("rowCount", rowcount);
            pars.Add("orderBy", orderby);
            Dictionary<string, VSqlDbType> outpars = new Dictionary<string, VSqlDbType>();
            outpars.Add("count", new VSqlDbType(SqlDbType.Int, -1));
            ReaderResponse rr = Execute.SPReader("Voice_ListAllUser", pars, outpars);
            total = Convert.ToInt32(rr.OutParams["count"]);
            if (rr.Table != null && rr.Table.Rows.Count > 0)
            {
                User[] retValue = new User[rr.Table.Rows.Count];
                for (int i = 0; i < rr.Table.Rows.Count; i++)
                {
                    retValue.SetValue(SetUser(rr.Table.Rows[i]), i);
                }
                return retValue;
            }
            else
                return null;
        }
        #endregion
        #region DML
        public static RegisterResponse RegisterUser(User u)
        {
            Dictionary<string, object> pars = new Dictionary<string, object>();
            pars.Add("UserId", u.UserID);
            pars.Add("Password", u.Password);
            pars.Add("FName",u.FName);
            pars.Add("LName",u.LName );
            pars.Add("Email",u.Email);
            pars.Add("Phone",u.Phone);
            pars.Add("PhotoId",u.PhotoId);
            pars.Add("Aboutme",u.AboutMe);
            pars.Add("DOB",u.DOB);
            pars.Add("Location",u.Location);
            pars.Add("Hobbies",u.Hobbies);
            pars.Add("Language", u.Language);
            Dictionary<string, VSqlDbType> outpars = new Dictionary<string, VSqlDbType>();
            outpars.Add("Result", new VSqlDbType(SqlDbType.VarChar, 20));
            NonQueryResponse nqr = Execute.SPNonQuery("Voice_CreateUser", pars, outpars);
            string res = nqr.OutParams["Result"].ToString();
            switch (res.ToLower())
            { 
                case "usercreated":
                    return RegisterResponse.UserCreated;
                case "useridnotavailable":
                    return RegisterResponse.UserIdNotAvailable;
                case "emailidinuse":
                    return RegisterResponse.EmailIdInUse;
                default:
                    return RegisterResponse.Error;
            }
        }
        public static ActivationResponse Activate(string userId, string password)
        {
            Dictionary<string, object> pars = new Dictionary<string, object>();
            pars.Add("UserId", userId);
            pars.Add("Password", password);
            Dictionary<string, VSqlDbType> outpars = new Dictionary<string, VSqlDbType>();
            outpars.Add("Result", new VSqlDbType(SqlDbType.VarChar, 20));
            NonQueryResponse nqr = Execute.SPNonQuery("Voice_ActivateUser", pars, outpars);
            string res = nqr.OutParams["Result"].ToString();
            switch (res.ToLower())
            {
                case "activated":
                    return ActivationResponse.Activated;
                case "invalidactivation":
                    return ActivationResponse.InvalidActivation;
                default:
                    return ActivationResponse.Error;
            }
        }
        public static void ToggleActivation(string userId)
        {
            Dictionary<string, object> pars = new Dictionary<string, object>();
            pars.Add("UserId", userId);
            Dictionary<string, VSqlDbType> outpars = new Dictionary<string, VSqlDbType>();
            Execute.SPNonQuery("Voice_ToggleUserActivation", pars, null);
        }
        #endregion
    }
}
